﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Sofire.DataComm.Remoting.Server.Settings
{
    /// <summary>
    /// 基本的远程配置基类。
    /// </summary>
    public abstract class SettingBase
    {
        #region Const String

        internal const string NameAttribute = "Name";
        internal const string VersionAttribute = "Version";
        internal const string ReturnsErrorAttribute = "ReturnsError";
        internal const string InstanceModeAttribute = "InstanceMode";
        internal const string PortAttribute = "Port";
        internal const string SessionExpirationAttribute = "SessionExpiration";
        internal const string MaxConnectionCountAttribute = "MaxConnectionCount";
        internal const string MaxReceiveBufferSizeAttribute = "MaxReceiveBufferSize";
        internal const string ListenBacklogAttribute = "ListenBacklog";
        internal const string TypeAttribute = "Type";
        internal const string ContractAttribute = "Contract";
        internal const string AddressAttribute = "Address";

        internal const string ApplicationElement = "Application";
        internal const string HostElement = "Host";
        internal const string ServiceElement = "Service";

        #endregion

        private string _Name;
        /// <summary>
        /// 表示配置的名称。
        /// </summary>
        public string Name
        {
            get
            {
                return this._Name;
            }
            internal set
            {
                this._Name = value;
            }
        }

        private bool _ReturnsError = true;
        /// <summary>
        /// 表示在远程发生错误时是否返回异常的信息。默认为 true。
        /// </summary>
        public bool ReturnsError
        {
            get
            {
                return this._ReturnsError;
            }
            internal set
            {
                this._ReturnsError = value;
            }
        }

        internal abstract SettingException CreateException(ServerErrorCode errorCode, string propertyName, string propertyValue);

        internal SettingException CreateException(ServerErrorCode errorCode, string propertyName)
        {
            return this.CreateException(errorCode, propertyName, null);
        }

        internal SettingException CreateException(ServerErrorCode errorCode)
        {
            return this.CreateException(errorCode, null, null);
        }

        internal string GetParentValue(XmlNode node, string name)
        {
            if(node == null) return null;
            var value = node.TryGetAttribute(name);
            if(string.IsNullOrEmpty(value)) return GetParentValue(node.ParentNode, name);
            return value;
        }

        internal virtual void Initialization(XmlElement element)
        {
            if(this._Name != null)
            {
                throw this.CreateException(ServerErrorCode.SettingInitialized);
            }
            var value = element.TryGetAttribute(NameAttribute);
            if(string.IsNullOrEmpty(value)) throw this.CreateException(ServerErrorCode.EmptyAttribute, NameAttribute);
            this._Name = value;

            value = this.GetParentValue(element, ReturnsErrorAttribute);
            if(!string.IsNullOrEmpty(value))
            {
                this._ReturnsError = value.ToLower() == "true";
            }

        }
    }
}
